#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>

using namespace std;

struct Treap
{
	struct node
	{
		int	key,val,size,cnt;
		node	*l,*r;
		node()
		{
			key=val=size=0;
			l=r=0;
		}
	} U[110000],*root;
	int	top,ALL;
	node	*Trash[110000];

	Treap()
	{
		top=0,ALL=0;
		root=ALLOC();
		root->val=0x80808080;
		root->key=rand();
		root->size=2;
		root->cnt=1;
		root->r=ALLOC();
		root->r->key=rand();
		root->r->val=0x7f7f7f7f;
		root->r->size=1;
		root->r->cnt=1;
		return ;
	}

	node*	ALLOC()
	{
		return top ? Trash[top--]:U+(++ALL);
	}
	void	RECYCLE(node *t)
	{
		Trash[++top]=t;
		memset(t,0,sizeof(node));
		return ;
	}

	void	update(node *t)
	{
		t->size=(t->l?t->l->size:0)+
			(t->r?t->r->size:0)+t->cnt;
		return ;
	}

	void	lturn(node *&t)
	{
		node *temp=t;
		t=t->r;
		temp->r=t->l;
		t->l=temp;
		update(t->l);
		update(t);
	}

	void	rturn(node *&t)
	{
		node *temp=t;
		t=t->l;
		temp->l=t->r;
		t->r=temp;
		update(t->r);
		update(t);
	}

	void	Insert(node *&t,const int d)
	{
		if(!t)
		{
			t=ALLOC();
			t->key=rand();
			t->val=d;
			t->size=1;
			t->cnt=1;
			return ;
		}
		t->size++;
		if(t->val==d)t->cnt++;
		else if(d>t->val)
		{
			Insert(t->r,d);
			if(t->r->key<t->key)lturn(t);
		}
		else
		{
			Insert(t->l,d);
			if(t->l->key<t->key)rturn(t);
		}
		return ;
	}

	void	Erase(node *&t,const int d)
	{
		if(!t)return ;
		if(t->val==d)
		{
			if(t->cnt>1)
			{
				t->cnt--,t->size--;
				return ;
			}
			if(!t->l || !t->r)
			{
				node *temp=t;
				t=(t->l?t->l:(t->r?t->r:0));
				RECYCLE(temp);
			}
			else if(t->l->key<t->r->key)rturn(t),Erase(t,d);
			else	lturn(t),Erase(t,d);
		}
		else if(d>t->val) t->size--,Erase(t->r,d);
		else	t->size--,Erase(t->l,d);
		return ;
	}

	int	Get_kth(node *t,const int pos)
	{
		if(!t)return 0;
		if(t->l && pos<=t->l->size)return Get_kth(t->l,pos);
		if(t->cnt+(t->l?t->l->size:0)>=pos)return t->val;
		return Get_kth(t->r,pos-(t->cnt+(t->l?t->l->size:0)));
	}

	void	insert(const int x)
	{
		Insert(root,x);
	}
	void	erase(const int x)
	{
		Erase(root,x);
	}
	int	get_kth(const int x)
	{
		return Get_kth(root,x+1);
	}
	void	print(node *t)
	{
		if(!t)return ;
		if(t->l)printf("%3ld(%11d:%3d)\t->%3ld(%10d:%3d)\n",t-U,t->val,t->cnt,t->l-U,t->l->val,t->l->cnt),print(t->l);
		if(t->r)printf("%3ld(%11d:%3d)\t->%3ld(%10d:%3d)\n",t-U,t->val,t->cnt,t->r-U,t->r->val,t->r->cnt),print(t->r);
	}
	void	print()
	{
		printf("*********************************\n");
		print(root);
	}
} S;

struct TAT
{
	int	l,r,k,v;
	bool	operator<(const TAT& temp)const
	{
		if(l!=temp.l)return l<temp.l;
		return r<temp.r;
	}
} rg[110000];

int	n,m,a[110000],Ans[110000];


int main()
{
	int	i,j;

	scanf("%d%d",&n,&m);
	for(i=1; i<=n; ++i)
		scanf("%d",&a[i]);
	for(i=1; i<=m; ++i)
		scanf("%d%d%d",&rg[i].l,&rg[i].r,&rg[i].k),rg[i].v=i;
	sort(rg+1,rg+m+1);
	for(i=rg[1].l; i<=rg[1].r; ++i)S.insert(a[i]);
	Ans[rg[1].v]=S.get_kth(rg[1].k);
	for(i=2; i<=m; ++i)
	{
		for(j=rg[i-1].l; j<min(rg[i].l,rg[i-1].r+1); ++j)
			S.erase(a[j]);
		for(j=max(rg[i-1].r+1,rg[i].l); j<=rg[i].r; ++j)
			S.insert(a[j]);
		for(j=rg[i].r+1; j<=rg[i-1].r; ++j)
			S.erase(a[j]);
		//S.print();
		Ans[rg[i].v]=S.get_kth(rg[i].k);
	}

	for(i=1; i<=m; ++i) printf("%d\n",Ans[i]);

	return 0;
}

